/**
 * 权限控制工具
 */

import { useUserStore } from '@/stores/user'

/**
 * 检查用户是否有指定权限
 * @param {string|Array} permission - 权限字符串或权限数组
 * @returns {boolean} 是否有权限
 */
export function hasPermission(permission) {
  const userStore = useUserStore()
  
  if (!permission) {
    return true
  }
  
  if (Array.isArray(permission)) {
    // 如果传入数组，检查是否有任一权限
    return permission.some(p => userStore.hasPermission(p))
  }
  
  return userStore.hasPermission(permission)
}

/**
 * 检查用户是否有所有指定权限
 * @param {Array} permissions - 权限数组
 * @returns {boolean} 是否有所有权限
 */
export function hasAllPermissions(permissions) {
  const userStore = useUserStore()
  return userStore.hasAllPermissions(permissions)
}

/**
 * 检查用户角色
 * @param {string|Array} role - 角色字符串或角色数组
 * @returns {boolean} 是否有指定角色
 */
export function hasRole(role) {
  const userStore = useUserStore()
  
  if (!role) {
    return true
  }
  
  if (Array.isArray(role)) {
    return role.includes(userStore.userRole)
  }
  
  return userStore.userRole === role
}

/**
 * 权限指令
 * 使用方式: v-permission="'user:view'" 或 v-permission="['user:view', 'user:edit']"
 */
export const permission = {
  mounted(el, binding) {
    const { value } = binding
    
    if (!hasPermission(value)) {
      el.style.display = 'none'
      // 或者移除元素
      // el.parentNode && el.parentNode.removeChild(el)
    }
  },
  
  updated(el, binding) {
    const { value } = binding
    
    if (!hasPermission(value)) {
      el.style.display = 'none'
    } else {
      el.style.display = ''
    }
  }
}

/**
 * 角色指令
 * 使用方式: v-role="'admin'" 或 v-role="['admin', 'manager']"
 */
export const role = {
  mounted(el, binding) {
    const { value } = binding
    
    if (!hasRole(value)) {
      el.style.display = 'none'
    }
  },
  
  updated(el, binding) {
    const { value } = binding
    
    if (!hasRole(value)) {
      el.style.display = 'none'
    } else {
      el.style.display = ''
    }
  }
}

/**
 * 权限混入
 * 可以在组件中使用 this.$hasPermission() 等方法
 */
export const permissionMixin = {
  methods: {
    $hasPermission(permission) {
      return hasPermission(permission)
    },
    
    $hasAllPermissions(permissions) {
      return hasAllPermissions(permissions)
    },
    
    $hasRole(role) {
      return hasRole(role)
    }
  }
}

/**
 * 路由权限守卫
 * @param {Object} to - 目标路由
 * @param {Object} from - 来源路由
 * @param {Function} next - 下一步函数
 */
export function routePermissionGuard(to, from, next) {
  const userStore = useUserStore()
  
  // 检查路由是否需要权限
  if (to.meta.permissions) {
    if (!hasAllPermissions(to.meta.permissions)) {
      // 没有权限，跳转到403页面或首页
      next('/403')
      return
    }
  }
  
  // 检查路由是否需要角色
  if (to.meta.roles) {
    if (!hasRole(to.meta.roles)) {
      // 没有角色权限，跳转到403页面或首页
      next('/403')
      return
    }
  }
  
  next()
}

/**
 * 按钮权限组件
 * 用于根据权限显示/隐藏按钮
 */
export const PermissionButton = {
  name: 'PermissionButton',
  props: {
    permission: {
      type: [String, Array],
      default: ''
    },
    role: {
      type: [String, Array],
      default: ''
    },
    fallback: {
      type: String,
      default: 'none' // 'none' | 'disabled'
    }
  },
  setup(props, { slots }) {
    const userStore = useUserStore()
    
    const hasPermission = computed(() => {
      if (props.permission) {
        if (Array.isArray(props.permission)) {
          return props.permission.some(p => userStore.hasPermission(p))
        }
        return userStore.hasPermission(props.permission)
      }
      return true
    })
    
    const hasRole = computed(() => {
      if (props.role) {
        if (Array.isArray(props.role)) {
          return props.role.includes(userStore.userRole)
        }
        return userStore.userRole === props.role
      }
      return true
    })
    
    const canShow = computed(() => {
      return hasPermission.value && hasRole.value
    })
    
    return () => {
      if (canShow.value) {
        return slots.default?.()
      }
      
      if (props.fallback === 'disabled') {
        return slots.default?.() ? h('span', { style: 'opacity: 0.5; pointer-events: none;' }, slots.default()) : null
      }
      
      return null
    }
  }
}
